package com.haiyou.sdk.log;

import com.haiyou.common.jdbc.DbType;
import com.haiyou.common.thread.ThreadManager;
import com.haiyou.common.thread.pool.FastActorThreadPoolExecutor;
import com.haiyou.data.sdk.account.log.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.concurrent.Executor;

@Slf4j
@Service
public class LogService {

    @Autowired
    private AdvertLogPersister advertLogPersister;
    @Autowired
    private LoginLogPersister loginLogPersister;
    @Autowired
    private RegisterLogPersister registerLogPersister;
    @Autowired
    private StageRecordLogPersister stageRecordLogPersister;
    @Autowired
    private OpenLogPersister openLogPersister;
    @Autowired
    private StartLogPersister startLogPersister;
    @Autowired
    private PlayerUidMappingTablePersister playerUidMappingTablePersister;
    @Autowired
    private OldPlayerLogPersister oldPlayerLogPersister;
    @Autowired
    private ExtraLogPersister extraLogPersister;
    public static final Executor executor;

    static {
        int nThreads = ThreadManager.getThreadCount(ThreadManager.ThreadEnum.game_log_thread);
        executor = new FastActorThreadPoolExecutor(nThreads,
                LogService.class.getSimpleName());
    }

    /**
     * 记录日志
     */
    public void log(LogType type, Object object) {
        executor.execute(() -> {
            try {
                switch (type) {
                    case register: {
                        registerLogPersister.save((RegisterLog) object);
                        break;
                    }
                    case login: {
                        loginLogPersister.save((LoginLog) object);
                        break;
                    }
                    case advert: {
                        advertLogPersister.save((AdvertLog) object);
                        break;
                    }
                    case open: {
                        openLogPersister.save((OpenLog) object);
                        break;
                    }
                    case stage: {
                        stageRecordLogPersister.insertOrUpdate((StageRecordLog) object);
                        break;
                    }
                    case start: {
                        startLogPersister.save((StartLog) object);
                        break;
                    }
                    case playerUidMapping: {
                        PlayerUidMappingTable table = (PlayerUidMappingTable) object;
                        StringBuilder values = new StringBuilder();
                        values.append("'").append(table.getUid()).append("',").append(table.getServerId()).append(",").append(table.getPlayerId());
                        String sql = "INSERT INTO `t_task_player_uid_mapping` (uid,server_id,player_id) VALUES (" + values.toString() + ");";
                        log.info("插入映射数据{}",sql);
                        playerUidMappingTablePersister.execute(DbType.LOG_DB, sql);
                        break;
                    }
                    case userInfoAuthorize:{
                        extraLogPersister.save((ExtraLog) object);
                        break;
                    }
                    default: {
                        log.error("LogService.log type is not found type:{},report:{}", type, object);
                    }
                }
            } catch (Exception e) {
                //注意 这段代码目的是防止
                //默认线程池拒绝策略导致主线程执行逻辑,异常后导致业务逻辑中断
                log.error(e.getMessage(), e);
            }
        });
    }

    public void deleteLog(long playerId,String reportUid) {
        executor.execute(() -> {
            OldPlayerLog oldPlayerLog = new OldPlayerLog();
            oldPlayerLog.setPlayerId(playerId);
            oldPlayerLog.setType(1);
            oldPlayerLog.setUuid(reportUid);
            oldPlayerLog.setNowTime(new Date());
            oldPlayerLogPersister.save(oldPlayerLog);
        });
    }

    /**
     * 注册日志
     *
     * @param playerId
     */
    public void logRegister(long playerId, int serverId, String uid) {
        RegisterLog registerLog = new RegisterLog();
        registerLog.setPlayerId(playerId);
        registerLog.setServerId(serverId);
        registerLog.setNowTime(new Date());
        log(LogType.register, registerLog);
        PlayerUidMappingTable playerUidMappingTable = new PlayerUidMappingTable();
        playerUidMappingTable.setUid(uid);
        playerUidMappingTable.setPlayerId(playerId);
        playerUidMappingTable.setServerId(serverId);
        log(LogType.playerUidMapping, playerUidMappingTable);
    }

    /**
     * 登录日志
     *
     * @param playerId
     */
    public void logLogin(long playerId, int serverId) {
        LoginLog loginLog = new LoginLog();
        loginLog.setPlayerId(playerId);
        loginLog.setServerId(serverId);
        loginLog.setNowTime(new Date());
        log(LogType.login, loginLog);
    }

    /**
     * 观看广告
     */
    public void logAdvert(String playerId, int adType, String advertId, boolean status, int serverId) {
        AdvertLog advertLog = new AdvertLog();
        advertLog.setAdId(adType);
        advertLog.setServerId(serverId);
        advertLog.setPlayerId(playerId);
        advertLog.setStatus(status);
        advertLog.setAdvertId(advertId);
        advertLog.setNowTime(new Date());
        log(LogType.advert, advertLog);
    }

    /**
     * 关卡日志
     *
     */
    public void logStage(int type,String uid, int stage, int serverId) {
        StageRecordLog stageRecordLog = new StageRecordLog();
        stageRecordLog.setId(uid);
        stageRecordLog.setType(type);
        stageRecordLog.setServerId(serverId);
        stageRecordLog.setStageId(stage);
        stageRecordLog.setDate(new Date());
        log(LogType.stage, stageRecordLog);
    }

    /**
     * 拉起日志
     *
     * @param playerId
     */
    public void logOpen(String playerId, int serverId) {
        OpenLog openLog = new OpenLog();
        openLog.setPlayerId(playerId);
        openLog.setServerId(serverId);
        openLog.setNowTime(new Date());
        log(LogType.open, openLog);
    }

    /**
     * 启动日志
     *
     * @param playerId
     */
    public void logStart(String playerId, int serverId) {
        StartLog openLog = new StartLog();
        openLog.setPlayerId(playerId);
        openLog.setServerId(serverId);
        openLog.setNowTime(new Date());
        log(LogType.start, openLog);
    }

    public void logExtra(int type, String playerId, int logId, int serverId){
        ExtraLog extraLog = new ExtraLog();
        extraLog.setType(type);
        extraLog.setPlayerId(playerId);
        extraLog.setServerId(serverId);
        extraLog.setParam(logId);
        log(LogType.userInfoAuthorize,extraLog);
    }

}
